#include "ImageLoader.h"
#include <stdio.h>
#include <iostream>


void ImageLoader::WriteFile(const char* fileName, unsigned int width, unsigned int height, Pics* image) {
    
	FileHeader header;
    BitmapInfoHeader bitmapInfo;
    header.bmtype[0] = 'B';
    header.bmtype[1] = 'M';
    header.iFileSize = 54 + width*height*3;
    header.reserved1 = 0;
    header.reserved2 = 0;
    header.iOffsetBits = 54;
    bitmapInfo.iSizeHeader = 40;
    bitmapInfo.iWidth = width;
    bitmapInfo.iHeight = height;
    bitmapInfo.iPlanes = 1;
    bitmapInfo.iBitCount = 24;
    bitmapInfo.Compression = 0;
    bitmapInfo.iSizeImage = width*height*3;
    bitmapInfo.iXPelsPerMeter = 0;
    bitmapInfo.iYPelsPerMeter = 0;
    bitmapInfo.iClrUsed = 0;
    bitmapInfo.iClrImportant = 0;
    
    FILE* fp = fopen(fileName,"wb");
    
    fwrite(&header, 1, sizeof(FileHeader), fp);
    fwrite(&bitmapInfo, 1, sizeof(BitmapInfoHeader),fp);
    
    for(unsigned int h = 0; h<height ; h++) {
    
        for(unsigned int w = 0; w<width; w++) {
            unsigned char r,g,b;
            
            int index = w * 3 + h*width * 3;
            if(image[index] > 1.0)
               image[index] = 1.0;
            if(image[index+1] > 1.0)
               image[index+1] = 1.0;
            if(image[index+2] > 1.0)
               image[index+2] = 1.0;
            
            r = (unsigned int)(image[index]*255.0);
            g = (unsigned int)(image[index+1]*255.0);
            b = (unsigned int)(image[index+2]*255.0);
            fwrite(&b, 1, 1, fp);
            fwrite(&g, 1, 1, fp);
            fwrite(&r, 1, 1, fp);
        }
    }     
    fclose(fp);
}
void ImageLoader::ReadFile(const char* fileName, Image* theImage) {
   
	BITMAPFILEHEADER header;
    BITMAPINFOHEADER bitmapInfo;
    FILE* fp = fopen(fileName,"rb");
    

    fread(&header,sizeof(BITMAPFILEHEADER),1, fp);
    fread(&bitmapInfo,sizeof(BITMAPINFOHEADER),1,fp);
	
	//get the size of the image data in bytes
	// file size - header size
	unsigned int size = header.bfSize - header.bfOffBits;

	//create a temporary buffer to store the image data
	//unsigned char *tempPixelData;
	unsigned char *tempPixelData = new unsigned char[size];
	
	//move file pointer to beginning of image data and read the data into buffer
	fseek ( fp, header.bfOffBits, SEEK_SET );
	
	fread(tempPixelData, 1, size, fp);
	
	
	//byteWidth is the width of the actual image in bytes
	//padWidth is the width of the image plus the extra padding
	int byteWidth, padWidth;

	//initially set both to the width of the image
	byteWidth=padWidth=(int)((flt)bitmapInfo.biWidth * (flt)bitmapInfo.biBitCount/8.0);

	//set width and height properties of the image
	theImage->width = byteWidth;
	theImage->height = abs(bitmapInfo.biHeight);			//height may be negative, indicating the 

	//add any extra space to bring each line to a DWORD boundary
	while(padWidth%4!=0) {
		padWidth++;
	}
	
	//at this point we have the padded, upside down and BGR image data read into a temporary buffer,
	//we now need to convert it into the proper format to be used by the ray tracer
	
	//allocate image data .. no padding
	theImage->imageData = new unsigned char[theImage->width * theImage->height];
	
    
	long bufpos = 0;				//position in image data we are reading pixel info into  
	long newpos = 0;				//corresponding position in the temp BGR buffer we are reading from
	for ( int y = 0; y < theImage->height; y++ )   {
		for ( int x = 0; x < theImage->width; x+=3 )
		{
			newpos = y * theImage->width + x;     
			bufpos = ( theImage->height - y - 1 ) * padWidth + x;

			theImage->imageData[newpos] = tempPixelData[bufpos + 2];       
			theImage->imageData[newpos + 1] = tempPixelData[bufpos+1]; 
			theImage->imageData[newpos + 2] = tempPixelData[bufpos];

			//printf("image data is %u, %u, %u\n",theImage->imageData[newpos],theImage->imageData[newpos+1],theImage->imageData[newpos+1]);
		}
	}
	delete [] tempPixelData;
    fclose(fp);
  
}
